# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: site-packages\cvsslib\cvss2\calculations.py
from .enums import *
from cvsslib.base_enum import NotDefined


def calculate_impact(conf, integ, avail):
    return D("10.41") * (1 - (1 - conf) * (1 - integ) * (1 - avail))


def calculate_exploitability(access, complexity, auth):
    return D("20") * access * complexity * auth


def calculate_base_score(run_calculation, impact_function):
    impact = run_calculation(impact_function)
    exploitability = run_calculation(calculate_exploitability)
    result = D("0.6") * impact + D("0.4") * exploitability - D("1.5")
    f_impact = 0 if impact == 0 else D("1.176")
    return round(result * f_impact, 1)


def calculate_temporal_score(base_score, exploit, remediation, confidence):
    return round(base_score * exploit * remediation * confidence, 1)


def calculate_adjusted_impact(
    conf_impact, conf_req, integ_impact, integ_req, avail_impact, avail_req
):
    return min(
        10,
        D("10.41")
        * (
            1
            - (1 - conf_impact * conf_req)
            * (1 - integ_impact * integ_req)
            * (1 - avail_impact * avail_req)
        ),
    )


def calculate_environmental_score(run_calculation, collat_damage, target_dist):
    adjusted_base_score = run_calculation(
        calculate_base_score, calculate_adjusted_impact
    )
    adjusted_temporal = run_calculation(calculate_temporal_score, adjusted_base_score)
    return round(
        (adjusted_temporal + (10 - adjusted_temporal) * collat_damage) * target_dist, 1
    )


def calculate(run_calculation, get):
    base_score = run_calculation(calculate_base_score, calculate_impact)
    temporal_metrics = {
        get(Exploitability),
        get(RemediationLevel),
        get(ReportConfidence),
    }
    if all((isinstance(e.value, NotDefined) for e in temporal_metrics)):
        temporal_score = None
    else:
        temporal_score = float(run_calculation(calculate_temporal_score, base_score))
    environment_metrics = {get(cls) for cls in ENVIRONMENTAL_METRICS}
    if all((isinstance(e.value, NotDefined) for e in environment_metrics)):
        environmental_score = None
    else:
        environmental_score = float(run_calculation(calculate_environmental_score))
    return (float(base_score), temporal_score, environmental_score)
